<template>
  <div ref="ganttRef" class="Z" :style="{
        width: computedWidth,
        height: computedHeight,
    }"></div>
</template>

<script lang="ts" setup>
import {ref, reactive, computed, onMounted, watch} from 'vue';
import {gantt} from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';

// 定义组件的 props
const props = defineProps({
  width: {
    type: Number,
    default: 0
  },
  height: {
    type: Number,
    default: 0
  },
  marginHeight: {
    type: Number,
    default: 200
  },
  dateType: {
    type: String,
    default: 'year'
  },
  ganttConfig: {
    type: Object as () => Partial<GanttConfig>,
    default: () => ({})
  },
  templatesConfig: {
    type: Object,
    default: () => ({})
  },
  ganttData: {
    type: Object as () => GanttData,
    default: () => ({data: [], links: []})
  }
});

// 定义甘特图数据接口
interface GanttData {
  data: any[];
  links: any[];
}

// 定义甘特图配置接口
export interface GanttConfig {
  autosize?: boolean;
  readonly?: boolean;
  show_grid?: boolean;
  scale_height?: number;
  bar_height?: number;
  row_height?: number;
  xml_date?: string;
  columns?: any[];
  scales?: any[];
  fit_tasks?: boolean;
  drag_project?: boolean;
  lightbox?: {
    sections?: any[];
  };
}

const emit = defineEmits(['rowDbClick', 'onTaskCreated', 'onAfterTaskDrag', 'onMouseMove', 'onTaskSelected']);
const ganttRef = ref<HTMLDivElement | null>(null);
const onTaskDblClickHandlerId = ref<string | null>(null);

// 计算宽度和高度
const computedWidth = computed(() => props.width === 0 ? 'calc(-20px + 100%)' : `${props.width}px`);
const computedHeight = computed(() => props.height === 0 ? `calc(100vh - ${props.marginHeight}px)` : `${props.height}px`);

const initGantt = () => {
  // 初始化甘特图配置
  const config: GanttConfig = reactive({
    autosize: false,
    readonly: true,
    show_grid: true,
    scale_height: 50,
    bar_height: 26,
    row_height: 32,
    xml_date: "%Y-%m-%d %H:%i",
    columns: [
      {
        name: 'text',
        label: '项目名称',
        tree: true,
        width: '200',
        align: 'left',
        template: (task) => task.parent ? task.text : `<div style="font-weight: 700">${task.text}</div>`
      },
      {name: 'person', label: '项目成员', width: '100', align: 'center'},
      // 可以添加更多列配置...
    ],
    scales: [],
    fit_tasks: true,
    drag_project: true,
    lightbox: {
      sections: [
        {name: 'description', height: 70, map_to: 'text', type: 'textarea', focus: true},
        {name: 'type', type: 'typeselect', map_to: 'type'},
        {name: 'time', type: 'duration', map_to: 'auto'}
      ]
    },
    ...props.ganttConfig // 合并用户自定义配置
  });

  // 根据 dateType 设置 scales
  if (props.dateType === 'year') {
    config.scales = [{unit: 'year', step: 1, date: ' %Y 年'}];
  } else if (props.dateType === 'month') {
    config.scales = [{unit: 'year', step: 1, date: ' %Y 年'}, {unit: 'month', step: 1, date: '%F'}];
  } else {
    config.scales = [{unit: 'month', step: 1, date: ' %Y 年  %F'}, {unit: 'day', step: 1, date: '%d'}];
  }

  gantt.locale.date = {
    month_full: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
    month_short: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
    day_full: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
    day_short: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
  };

  gantt.locale.labels = {
    dhx_cal_today_button: '今天',
    day_tab: '日',
    week_tab: '周',
    month_tab: '月',
    new_event: '新建日程',
    icon_save: '保存',
    icon_cancel: '关闭',
    icon_details: '详细',
    icon_edit: '编辑',
    icon_delete: '删除',
    confirm_closing: '请确认是否撤销修改!', //Your changes will be lost, are your sure?
    confirm_deleting: '是否删除计划?',
    section_description: '描述:',
    section_time: '时间范围:',
    section_type: '类型:',
    section_text: '计划名称:',
    section_test: '测试:',
    section_projectClass: '项目类型:',
    taskProjectType_0: '项目任务',
    taskProjectType_1: '普通任务',
    section_head: '负责人:',
    section_priority: '优先级:',
    taskProgress: '任务状态',
    taskProgress_0: '未开始',
    taskProgress_1: '进行中',
    taskProgress_2: '已完成',
    taskProgress_3: '已延期',
    taskProgress_4: '搁置中',
    section_template: 'Details',
    /* grid columns */
    column_text: '计划名称',
    column_start_date: '开始时间',
    column_duration: '持续时间',
    column_add: '',
    column_priority: '难度',
    /* link confirmation */
    link: '关联',
    confirm_link_deleting: '将被删除',
    message_ok: '确定',
    message_cancel: '取消',
    link_start: ' (开始)',
    link_end: ' (结束)',

    type_task: '任务',
    type_project: '项目',
    type_milestone: '里程碑',
    minutes: '分钟',
    hours: '小时',
    days: '天',
    weeks: '周',
    months: '月',
    years: '年'
  };

  // 设置甘特图配置
  for (const key in config) {
    if (config.hasOwnProperty(key)) {
      gantt.config[key] = config[key];
    }
  }

  for (const key in props.templatesConfig) {
    if (props.templatesConfig.hasOwnProperty(key)) {
      gantt.templates[key] = props.templatesConfig[key];
    }
  }

  // 绑定双击事件
  if (onTaskDblClickHandlerId.value) {
    gantt.detachEvent(onTaskDblClickHandlerId.value);
  }
  onTaskDblClickHandlerId.value = gantt.attachEvent('onTaskDblClick',
      (id, e) => {
        emit('rowDbClick', id);
        // 为true会开启自带弹窗等功能
        return false;
      },
      {id: 'onTaskDblClick'}
  );

  gantt.attachEvent("onTaskCreated", (task) => {
    // 点击“+”进行添加任务操作触发
    // 必须关闭只读模式
    emit('onTaskCreated', task);
    return false;
  })

  gantt.attachEvent("onAfterTaskDrag", (id, mode, e) => {
    // 用户拖拽任务后释放鼠标之后，应用更改之前触发
    emit('onAfterTaskDrag', {id, mode, e});
    return false
  })

  gantt.attachEvent("onMouseMove", (id, e) => {
    // 用户悬停Gantt时触发
    emit('onMouseMove', {id, e});
    // 该方法只要悬停到gantt 区域就会触发
  })

  gantt.attachEvent("onTaskSelected", (id) => {
    // 用户选择任务时触发
    emit('onTaskSelected', id);
    return false
  })

//   // 监听Gantt容器的dragover事件以允许放置
//   gantt.$container.addEventListener('dragover', (event)=> {
//     event.preventDefault(); // 阻止默认行为
//   });
//
// // 监听Gantt容器的drop事件以处理放置
//   gantt.attachEvent('onTaskDrag', (event) => {
//
//   });

  gantt.plugins({
    click_drag: true,//提供通过拖放创建和选择任务的可能性。
    auto_scheduling: true,//允许您根据任务之间的关系自动安排任务。
    marker: true
  });

  // 初始化甘特图
  gantt.i18n.setLocale('cn');
  gantt.init(ganttRef.value);
  gantt.parse(props.ganttData);


};

// 组件挂载后初始化甘特图
onMounted(() => {
  initGantt();
});

// 监听甘特图数据变化，重新解析数据
watch([() => props.ganttData.data, () => props.ganttData.links], ([n1, n2], [o1, o2]) => {
  gantt.clearAll();
  gantt.parse(props.ganttData);
});
//
// // 监听配置变化，重新初始化甘特图（如果需要更细粒度的控制，可以拆分监听）
watch([() => props.ganttConfig, () => props.dateType], () => {
  gantt.clearAll();
  initGantt();
}, {deep: true});

</script>

<style scoped>
.Z {
  /* 样式可以根据需要添加 */

  /*--dhx-gantt-task-background: #e4e4e4;*/
  --dhx-gantt-link-background: #ffa011;
  --dhx-gantt-link-background-hover: #ffa011;

  ::v-deep(.gantt_row.gantt_row_project:hover) {
    background: #e4e4e4 !important;
  }

  ::v-deep(.gantt_row.gantt_row_task:hover) {
    background: #e4e4e4 !important;
  }

  ::v-deep(.gantt_selected) {
    background: #ececec !important;
  }

  ::v-deep(.gantt_task_row.gantt_selected .gantt_task_cell) {
    background: #ececec !important;
    border-right-color: #ebebeb !important;
  }

  ::v-deep(.gantt_grid_head_cell) {
    background-color: #f7f7f7;
    font-weight: 700;
    font-size: 13px;
    color: #000000;
  }

  ::v-deep(.gantt_scale_cell) {
    background-color: #f7f7f7;
    font-weight: 700;
    color: #000000 !important;
    border-bottom: 1px solid #ebebeb;
  }

  ::v-deep(.gantt_task_line) {
    border: none !important;
    box-shadow: none !important;
  }

  ::v-deep(.gantt_task_progress_wrapper) {
    border: none !important;
    background-color: #E1E1E1;
    border-radius: 8px;
  }

  ::v-deep(.gantt_task_content) {

  }

  ::v-deep(.gantt_task_line) {
    border: none;
    border-radius: 8px;
    background-color: transparent;
  }

  ::v-deep(.gantt_success .gantt_task_progress) {
    background: #13C400 !important;
    border: none !important;
  }

  ::v-deep(.gantt_primary .gantt_task_progress) {
    background: #3A84FF !important;
    border: none !important;
  }

  ::v-deep(.gantt_begined .gantt_task_progress) {
    background: #9a9a9a !important;
    border: none !important;
  }

  ::v-deep(.gantt_info .gantt_task_progress) {
    background: #FE0000 !important;
    border: none !important;
  }

  ::v-deep(.gantt_warning .gantt_task_progress) {
    background: #FF7700 !important;
    border: none !important;
  }
}
</style>
